package com.cfweb.controller.app;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cfweb.api.ServiceApi;
import com.cfweb.controller.LoginHandler;
import com.cfweb.dao.CfServiceBrokerMapper;
import com.cfweb.dao.CfServiceInstanceMapper;
import com.cfweb.dao.CfServiceMapper;
import com.cfweb.domain.CfService;
import com.cfweb.domain.CfServiceExample;
import com.cfweb.domain.CfServiceInstance;
import com.cfweb.domain.CfServiceInstanceExample;
import com.cfweb.pojo.CfServiceInstanceWithType;
import com.cfweb.pojo.DatabaseServiceWithBroker;
import com.cfweb.util.ExtJSResponse;
import com.cfweb.util.StringUtil;

/**
 * 
 * @author (yufangjiang) Dec 2, 2014
 */
@Service
@Path("/service")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ServiceManagement {
  /**
   * LOGER
   */
  private static Logger logger = Logger.getLogger(ServiceManagement.class);

  /**
   * 服务实例名称的长度
   */
  private static Integer SERVICE_INSTANCE_NAME_LENGTH = 5;

  /**
   * 创建service-broker用到的用户名
   */
  private static final String USERNAME = "admin";
  /**
   * 创建service-broker用到的密码
   */
  private static final String PASSWORD = "123";

  /**
   * session
   */
  @Autowired
  private HttpSession session;
  /**
   * 服务
   */
  @Autowired
  private CfServiceMapper cfsMapper;
  /**
   * 服务实例
   */
  @Autowired
  private CfServiceInstanceMapper serviceMapper;
  /**
   * servicebroker
   */
  @Autowired
  private CfServiceBrokerMapper cfsBrokerMapper;

  /**
   * 根据服务类型获取服务实例
   * 
   * @param category
   *          第一大類（数据库服务、应用服务 &）
   * @param subcategory
   *          第二大类（oracle、mysql &）
   * @return
   * @throws Exception
   */
  @SuppressWarnings("unchecked")
  @Path("/list")
  @GET
  public ExtJSResponse list(@QueryParam("first") String category,
      @QueryParam("second") String subcategory) throws Exception {
    Integer cat = null;
    Integer subcat = null;
    if (StringUtil.isNotEmpty(category)) {
      cat = Integer.valueOf(category);
    }

    if (StringUtil.isNotEmpty(subcategory)) {
      subcat = Integer.valueOf(subcategory);
    }

    List<CfServiceInstanceWithType> services = serviceMapper.selectServiceByParams(cat, subcat,
        (String) session.getAttribute(LoginHandler.ORG),
        (String) session.getAttribute(LoginHandler.SPACE));
    Map<String, CfServiceInstanceWithType> servicesMap = new HashMap<String, CfServiceInstanceWithType>();
    for (CfServiceInstanceWithType service : services) {
      servicesMap.put(service.getServiceInstanceName(), service);
    }

    List<CfServiceInstanceWithType> response = new ArrayList<>();
    for (Map<String, Object> cs : ServiceApi.getServices(session)) {
      String name = (String) ((Map<String, Object>) cs.get("entity")).get("name");
      if (servicesMap.containsKey(name)) {
        response.add(servicesMap.get(name));
      }
    }
    return ExtJSResponse.successResWithData(response);
  }


  /**
   * 列出集群支持的服务
   * 
   * @param type
   * @return
   */
  @Path("/listall")
  @GET
  public ExtJSResponse listall(@QueryParam("type") Integer type) {
    CfServiceExample example = new CfServiceExample();
    if (type != null) {
      example.createCriteria().andSerTypeEqualTo(type);
    }
    List<CfService> ls = cfsMapper.selectByExample(example);
    List<Map<String, Object>> list = new ArrayList<>();
    for (CfService cfs : ls) {
      Map<String, Object> map = new HashMap<String, Object>();
      List<String> cfsb = cfsBrokerMapper.selectByServiceId(cfs.getId());
      map.put("id", cfs.getId());
      map.put("serName", cfs.getSerName());
      map.put("serImg", cfs.getSerImg());
      map.put( "serLargeImg",cfs.getSerLargeImg() );
      map.put("serPrefix", cfs.getSerPrefix());
      map.put( "serDesCn", cfs.getSerDescChn() );
      map.put( "serDesEng", cfs.getSerDescEng() );
      map.put("brokers", cfsb);
      if (cfsb.size() == 1 && cfsb.get(0) == null || cfsb.size() == 0) {
        map.put("type", 0);
      } else {
        map.put("type", 1);
      }
      list.add(map);
    }
    return ExtJSResponse.successResWithData(list);
  }


  /**
   * 根据guid获取servicebroker
   * 
   * @param lguid
   *          以“，”分割的guid字符串
   * @return
   * @throws Exception
   */
  @Path("/listforbroker")
  @GET
  public ExtJSResponse listforbroker(@QueryParam("lguid") String lguid) throws Exception {
    System.out.println(lguid);
    String[] lg = lguid.split(",");
    List<Map<String, Object>> lr = new ArrayList<Map<String, Object>>();
    for (String guid : lg) {
      List<Map<String, Object>> tlr = ServiceApi.listServiceBroker(session, guid);
      if (tlr != null) {
        lr.addAll(tlr);
      }
    }
    return ExtJSResponse.successResWithData(lr);
  }

  /**
   * 创建servicebroker
   * 
   * @param name
   * @param url
   * @return
   */
  @Path("/createbroker")
  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public ExtJSResponse createbroker(@FormParam("name") String name, @FormParam("url") String url) {
//    CloudFoundryClient client = (CloudFoundryClient) session.getAttribute(LoginHandler.CLIENT);
//    CloudServiceBroker csb = new CloudServiceBroker(USERNAME, PASSWORD, url);
//    csb.setName(name);
//    client.createServiceBroker(csb);
    return ExtJSResponse.successRes();
  }

  /**
   * 更新servicebroker
   * 
   * @param name
   * @param url
   * @return
   */
  @Path("/updatebroker")
  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public ExtJSResponse updatebroker(@FormParam("name") String name, @FormParam("url") String url) {
//    CloudFoundryClient client = (CloudFoundryClient) session.getAttribute(LoginHandler.CLIENT);
//    CloudServiceBroker csb = new CloudServiceBroker(USERNAME, PASSWORD, url);
//    csb.setName(name);
//    client.updateServiceBroker(csb);
    return ExtJSResponse.successRes();
  }

  /**
   * 删除servicebroker
   * 
   * @param name
   * @return
   */
  @Path("/deletebroker")
  @GET
  public ExtJSResponse deletebroker(@QueryParam("name") String name) {
//    CloudFoundryClient client = (CloudFoundryClient) session.getAttribute(LoginHandler.CLIENT);
//    client.deleteServiceBroker(name);
    return ExtJSResponse.successRes();
  }


  /**
   * serviceplan更新为public
   * 
   * @param name
   * @param visibility
   * @return
   */
  @Path("/updateVisibility")
  @GET
  public ExtJSResponse updateVisibility(@QueryParam("name") String name,
      @QueryParam("visibility") boolean visibility) {
//    CloudFoundryClient client = (CloudFoundryClient) session.getAttribute(LoginHandler.CLIENT);
//    client.updateServicePlanVisibilityForBroker(name, visibility);
    return ExtJSResponse.successRes();
  }



  /**
   * 创建服务实例
   * 
   * @param service
   * @param plan
   * @param planId
   * @param prefix
   * @param typeId
   * @param visibility
   * @return
   * @throws Exception
   */
  @Path("/createinstance")
  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public ExtJSResponse createInstance(@FormParam("service") String service,
      @FormParam("plan") String plan, @FormParam("planId") String planId,
      @FormParam("prefix") String prefix, @FormParam("typeId") Integer typeId,
      @FormParam("visibility") boolean visibility) throws Exception {
    String name = prefix + "_" + "" + produceServiceName(SERVICE_INSTANCE_NAME_LENGTH);
    if (ServiceApi.createServiceInstance(session, service, planId, name, visibility)) {
      CfServiceInstance serviceIns = new CfServiceInstance();
      serviceIns.setCreateTime(new Date());
      serviceIns.setService(service);
      serviceIns.setPlan(plan);
      serviceIns.setUpdateTime(new Date());
      serviceIns.setServiceInstanceName(name);
      serviceIns.setOrg((String) session.getAttribute(LoginHandler.ORG));
      serviceIns.setSpace((String) session.getAttribute(LoginHandler.SPACE));
      serviceIns.setServiceTypeId(typeId);
      serviceMapper.insert(serviceIns);
    }
    return ExtJSResponse.successRes();
  }


  /**
   * 删除服务实例
   * 
   * @param serviceName
   * @return
 * @throws Exception 
   */
  @Path("/deleteinstance")
  @POST
  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
  public ExtJSResponse deleteInstance(@FormParam("serviceName") String serviceName) throws Exception {
	ServiceApi.deleteServiceInstance(serviceName, session);
    CfServiceInstanceExample example = new CfServiceInstanceExample();
    example.createCriteria().andServiceEqualTo(serviceName);
    serviceMapper.deleteByExample(example);
    return ExtJSResponse.successRes();
  }


  /**
   * 自动生成服务实例的名称
   * 
   * @param length
   * @return
   */
  private String produceServiceName(int length) {
    String base = "abcdefghijklmnopqrstuvwxyz0123456789";
    Random random = new Random();
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < length; i++) {
      int number = random.nextInt(base.length());
      sb.append(base.charAt(number));
    }
    return sb.toString();
  }

  /**
   * 获取服务
   * 
   * @param type
   * @return
   */
  @Path("/getDatabaseSer")
  @GET
  public ExtJSResponse getDatabaseSerBroker(@QueryParam("type") Integer type) {
    List<DatabaseServiceWithBroker> lsbroker = new ArrayList<DatabaseServiceWithBroker>();
    CfServiceExample example = new CfServiceExample();
    if (type != null) {
      example.createCriteria().andSerTypeEqualTo(type);
    }
    List<CfService> ls = cfsMapper.selectByExample(example);
    for (int i = 0; i < ls.size(); i++) {
      CfService cfs = ls.get(i);
      List<String> cfsb = cfsBrokerMapper.selectByServiceId(cfs.getId());
      DatabaseServiceWithBroker databaseWithBroker = new DatabaseServiceWithBroker();
      databaseWithBroker.setId(cfs.getId());
      databaseWithBroker.setSerName(cfs.getSerName());
      databaseWithBroker.setSerTemImg(cfs.getSerLargeImg());
      databaseWithBroker.setSerPrefix(cfs.getSerPrefix());
      databaseWithBroker.setBrokers(cfsb);
      if (cfsb.size() == 1 && cfsb.get(0) == null || cfsb.size() == 0) {
        databaseWithBroker.setType(0);
      } else {
        databaseWithBroker.setType(1);
      }
      lsbroker.add(databaseWithBroker);
    }
    return ExtJSResponse.successResWithData(lsbroker);
  }
}
